﻿using Autofac;
using KWT.DRG_DIP.API.Infrastructure;
using KWT.DRG_DIP.DB;
using KWT.DRG_DIP.DO.System;
using KWT.DRG_DIP.DTO.Settlement.List;
using KWT.DRG_DIP.DTO.Statistic.Category;
using KWT.DRG_DIP.DTO.Statistic.Doctor;
using KWT.DRG_DIP.DTO.Statistic.MedicalGroup;
using KWT.DRG_DIP.DTO.Statistic.Overview;
using KWT.DRG_DIP.ISvc;
using KWT.DRG_DIP.PO.Basic;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NetTopologySuite.Algorithm;

namespace KWT.DRG_DIP.API.Controllers.Statistic
{
    /// <summary>
    /// 医生综合分析
    /// </summary>
    [ApiExplorerSettings(GroupName = "statistic")]
    public class DoctorController : StatisticControllerBase
    {
        public EFContext ef { get; set; }
        private readonly IComponentContext componentContext;
        public DoctorController(IComponentContext _componentContext)
        {
            componentContext = _componentContext;
        }

        /// <summary>
        /// 模糊查询医生
        /// </summary>
        /// <param name="areaID">院区ID</param>
        /// <param name="keyword">关键字</param>
        /// <returns></returns>
        [HttpGet]
        public OutputResult GetDcName([FromQuery] string areaID, [FromQuery] string keyword)
        {
            var q = from x in ef.Set<Sys_User>().AsQueryable()
                    join y in ef.Set<User_AreaRoleDeptCategory>().AsQueryable() on x.UserID equals y.UserID
                    where EF.Functions.Like(x.RealName, $"%{keyword}%") && y.RoleID == "4" && y.AreaID == areaID
                    select new { DcName = x.RealName, DcCode = x.NickName };
            var list = q.Take(10).AsNoTracking().ToList();
            return Output(list.Count > 0, "", "", list);
        }

        /// <summary>
        /// 医生综合分析（列表）
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(Output<PageList<DTO.Statistic.Doctor.OutPageList>>), 200)]
        public OutputResult PageList(DTO.Statistic.Doctor.InPageList dto)
        {
            var statisticSvc = componentContext.ResolveNamed<IStatisticSvc>(CurrentUser.UsePolicy);
            var result = statisticSvc.DoctorPageList(dto);
            return Output(result.total > 0, "", "", new PageList<DTO.Statistic.Doctor.OutPageList>() { List = result.list, Total = result.total });
        }

        /// <summary>
        /// 医生综合分析（图表）
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        public OutputResult Part1(InDoctor dto)
        {
            var paras = new { dto.StartDate, dto.EndDate, dto.CategoryID, dto.AreaID };
            string sql1 = @"select sum(cnt) value from (
select count(1) cnt,c.DcCode from sys_list a 
left join list_chargeinfo b on a.ListID=b.ListID
inner join list_personinfo c on c.ListID=a.ListID
where SettleDate>=@StartDate and SettleDate<=@EndDate and a.AreaID=@AreaID ";
            if (!string.IsNullOrEmpty(dto.CategoryID))
            {
                sql1 += " and CategoryID=@CategoryID ";
            }
            sql1 += @" group by DcCode
having sum(b.Remain)>=0) a";
            int yy = Convert.ToInt32(dapper.ExecuteScalar(sql1, paras));

            string sql2 = @"select sum(cnt) value from (
select count(1) cnt,c.DcCode from sys_list a 
left join list_chargeinfo b on a.ListID=b.ListID
inner join list_personinfo c on c.ListID=a.ListID
where SettleDate>=@StartDate and SettleDate<=@EndDate and a.AreaID=@AreaID";
            if (!string.IsNullOrEmpty(dto.CategoryID))
            {
                sql2 += " and CategoryID=@CategoryID ";
            }
            sql2 += @" group by DcCode
having sum(b.Remain)<0) a";
            int ks = Convert.ToInt32(dapper.ExecuteScalar(sql2, paras));

            string sql3 = @"select sum(b.Remain) Amount,CONCAT(c.DcName,' - ',c.DcCode) doc_name from sys_list a 
left join list_chargeinfo b on a.ListID=b.ListID
inner join list_personinfo c on c.ListID=a.ListID
where SettleDate>= @StartDate and SettleDate<= @EndDate and a.AreaID = @AreaID ";
            if (!string.IsNullOrEmpty(dto.CategoryID))
            {
                sql3 += " and CategoryID=@CategoryID ";
            }
            sql3 += @" group by c.DcName,DcCode
having sum(b.Remain)>=0
order by Amount desc
limit 5";

            var list3 = dapper.Select<DTO.Statistic.Doctor.OutPart1Bar>(sql3, paras);

            string sql4 = @"select sum(b.Remain) Amount,CONCAT(c.DcName,' - ',c.DcCode) doc_name  from sys_list a 
left join list_chargeinfo b on a.ListID=b.ListID
inner join list_personinfo c on c.ListID=a.ListID
where SettleDate>=@StartDate and SettleDate<=@EndDate and a.AreaID=@AreaID ";
            if (!string.IsNullOrEmpty(dto.CategoryID))
            {
                sql4 += " and CategoryID=@CategoryID ";
            }
            sql4 += @"group by c.DcName,DcCode
having sum(b.Remain)<0
order by Amount desc
limit 5";

            var list4 = dapper.Select<DTO.Statistic.Doctor.OutPart1Bar>(sql4, paras);

            var result = new DTO.Statistic.Doctor.OutPart1()
            {
                yy = yy,
                ks = ks,
                Bar1 = list3.ToList(),
                Bar2 = list4.ToList(),
            };
            return Output(true, "", "", result);
        }

        /// <summary>
        /// 结余趋势-费用结构-收费项目TOP10(详情页)
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        public OutputResult DetailPart1(InDoctor dto)
        {
            if (string.IsNullOrEmpty(dto.DcCode))
            {
                return Fail("请选择一位医生！");
            }
            var dt1 = Convert.ToDateTime(dto.StartDate);
            var dt2 = Convert.ToDateTime(dto.EndDate);
            string dt = dt1.Year == dt2.Year && dt1.Month == dt2.Month ? "%m-%d" : "%Y-%m";

            string sql1 = @"select sum(Total) total,sum(Remain) remain,DATE_FORMAT(SettleDate, @dt) fmt_date from sys_list a
left join list_chargeinfo b on a.ListID=b.ListID
left join list_personinfo c on a.ListID=c.ListID
where SettleDate>=@StartDate and SettleDate<=@EndDate and c.DcCode=@DcCode and a.AreaID=@AreaID
group by fmt_date
order by fmt_date";
            var list1 = dapper.Select<dynamic>(sql1, new { dto.StartDate, dto.EndDate, dto.DcCode, dto.AreaID, dt });
            var series1 = new List<Series>
            {
                new() { name = "总收入", datas = [.. list1.Select(x => x.total).Cast<decimal>()], type = "line", stack = "Total" },
                new() { name = "支付差", datas = [.. list1.Select(x => x.remain).Cast<decimal>()], type = "line", stack = "Total" },
            };


            var line1 = new ECharts_Line()
            {
                legend = ["总收入", "支付差"],
                xAxis = [.. list1.Select(x => x.fmt_date).Cast<string>().Distinct()],
                Series = series1,
            };

            string sql2 = @"select sum(amount) value ,ItemName name from sys_list a
left join chargeinfo_item b on a.ListID=b.ListID
left join list_personinfo c on a.ListID=c.ListID
where SettleDate>=@StartDate and SettleDate<=@EndDate and c.DcCode=@DcCode and a.AreaID=@AreaID
GROUP BY ItemName";
            var list2 = dapper.Select<PieData>(sql2, new { dto.StartDate, dto.EndDate, dto.DcCode, dto.AreaID });

            string sql3 = @"select sum(Amount) Amount,b.ItemName from sys_list a
left join chargeinfo_item b on a.ListID=b.ListID
left join list_personinfo c on a.ListID=c.ListID
where SettleDate>=@StartDate and SettleDate<=@EndDate and c.DcCode=@DcCode and a.AreaID=@AreaID
GROUP BY ItemName
order by Amount desc
limit 10";
            var list3 = dapper.Select<ChargeInfoItem>(sql3, new { dto.StartDate, dto.EndDate, dto.DcCode, dto.AreaID });

            var result = new DTO.Statistic.Category.OutDetailPart1()
            {
                Line = line1,
                Pie = list2.ToList(),
                ChargeInfoItems = list3.ToList(),
            };
            return Output(true, "", "", result);
        }

        /// <summary>
        /// 病组列表(详情页)
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(Output<PageList<DTO.Statistic.Doctor.OutDetailPageList>>), 200)]
        public OutputResult DetailPageList(DTO.Statistic.Doctor.InDetailPageList dto)
        {
            if (string.IsNullOrEmpty(dto.DcCode))
            {
                return Fail("请选择一位医生！");
            }
            var statisticSvc = componentContext.ResolveNamed<IStatisticSvc>(CurrentUser.UsePolicy);
            var result = statisticSvc.DetailDoctorPageList(dto);
            return Output(result.total > 0, "", "", new PageList<DTO.Statistic.Doctor.OutDetailPageList>() { List = result.list, Total = result.total });
        }
    }
}
